package pl.egraveyard.validator;

import java.util.ResourceBundle;

import org.springframework.util.StringUtils;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;

import pl.egraveyard.bo.UzytkownikBO;
import pl.egraveyard.command.RegisterCommand;
import pl.egraveyard.util.Constants;
import pl.egraveyard.util.ValidationUtil;

/**
 * Walidator dla okna rejestracji nowych uzytkownikow
 * @author gunos
 *
 */
public class RegisterValidator implements Validator{
	private static final Integer MAX_PHONE_LENGTH = 9;
	private static final Integer MAX_LOGIN_LENGTH = 20;
	private static final Integer MAX_NAME_LENGTH = 50;
	private static final Integer MAX_PESEL_LENGTH = 11;
	private static final Integer MAX_STREET_LENGTH = 200;
	private static final String NUMER_TEL_REGEXP = "\\d{9}";
	private static final String NUMER_TEL_ZLY_FORMAT = 
		"register.error.numer_telefonu_bledny_format";
	private static final String POLE_WYMAGANE = "register.error.pole_jest_wymagane";
	private static final String POLE_ZA_DLUGIE = "register.error.pole_za_dlugie";
	private static final String HASLA_NIE_SA_IDENTYCZNE = 
		"register.error.hasla_nie_sa_identyczne";
	private static final String LOGIN_ISTNIEJE = "register.error.login_istnieje";
	private static final String HASLO_NIE_MOZE_BYC_JAK_DANE = "register.error.haslo_jako_dane";
	private static final String BLEDNY_FORMAT_PESELU = "register.error.zly_pesel";
	private static final String BLEDNA_LICZB_ZNAKOW_W_PESELU = 
		"register.bledna_liczba_znakow_w_pesel";
	private static final String BLEDNY_FORMAT_NUMERU_DOMU = "register.error.zly_numer_lokalu";
	private static final String BLEDNY_FORMAT_KODU = "register.error.zly_kod_pocztowy";
	private static final String KOD_NIE_NALEZY_DO_MIASTA = 
		"register.error.kod_pocztowy_nie_nalezy_do_miasta";
	private static final String POLE_IMIE = ResourceBundle
			.getBundle(Constants.MESSAGES_BUNDLE).getString("register.name");
	private static final String POLE_NAZWISKO = 
		ResourceBundle.getBundle(Constants.MESSAGES_BUNDLE).getString("register.surename");
	private static final String POLE_HASLO = 
		ResourceBundle.getBundle(Constants.MESSAGES_BUNDLE).getString("register.password");
	private static final String POLE_POWT_HASLO = 
		ResourceBundle.getBundle(Constants.MESSAGES_BUNDLE).getString("register.repeated_password");
	private static final String POLE_LOGIN = 
		ResourceBundle.getBundle(Constants.MESSAGES_BUNDLE).getString("register.login");
	private static final String POLE_PESEL = 
		ResourceBundle.getBundle(Constants.MESSAGES_BUNDLE).getString("register.personal_number");
	private static final String POLE_ULICA = 
		ResourceBundle.getBundle(Constants.MESSAGES_BUNDLE).getString("register.street");
	private static final String POLE_TELEFON =
		ResourceBundle.getBundle(Constants.MESSAGES_BUNDLE).getString("register.telephone_number");
	
	private UzytkownikBO uzytkownikBO;
	private ValidationUtil validationUtil;

	/**
	 * @param validationUtil the validationUtil to set
	 */
	public void setValidationUtil(ValidationUtil validationUtil) {
		this.validationUtil = validationUtil;
	}

	/**
	 * @param uzytkownikBO the uzytkownikBO to set
	 */
	public void setUzytkownikBO(UzytkownikBO uzytkownikBO) {
		this.uzytkownikBO = uzytkownikBO;
	}

	/**
	 * {@inheritDoc}
	 */
	@SuppressWarnings("rawtypes")
	@Override
	public boolean supports(Class clazz) {
		return RegisterCommand.class.equals(clazz);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void validate(Object target, Errors errors) {
		RegisterCommand cmd = (RegisterCommand) target;
		if (!StringUtils.hasText(cmd.getLogin())) {
			errors.rejectValue("login", POLE_WYMAGANE,
					new String[] { POLE_LOGIN }, null);
		} else if (cmd.getLogin().length() > MAX_LOGIN_LENGTH) {
			errors.rejectValue("login", POLE_ZA_DLUGIE, new String[] {
					POLE_LOGIN, String.valueOf(MAX_LOGIN_LENGTH) }, null);
		} else if (uzytkownikBO.readUser(cmd.getLogin()) != null
				|| uzytkownikBO.readCustomer(cmd.getLogin()) != null) {
			errors.rejectValue("login", LOGIN_ISTNIEJE);
		}
		
		
		if (!StringUtils.hasText(cmd.getName())) {
			errors.rejectValue("name", POLE_WYMAGANE,
					new String[] { POLE_IMIE }, null);
		} else if (cmd.getName().length() > MAX_NAME_LENGTH) {
			errors.rejectValue("name", POLE_ZA_DLUGIE, new String[] {
					POLE_IMIE, String.valueOf(MAX_NAME_LENGTH) }, null);
		}

		if (!StringUtils.hasText(cmd.getSurename())) {
			errors.rejectValue("surename", POLE_WYMAGANE,
					new String[] { POLE_NAZWISKO }, null);
		} else if (cmd.getSurename().length() > MAX_NAME_LENGTH) {
			errors.rejectValue("surename", POLE_ZA_DLUGIE, new String[] {
					POLE_NAZWISKO, String.valueOf(MAX_NAME_LENGTH) }, null);
		}

		if (!StringUtils.hasText(cmd.getPassword())) {
			errors.rejectValue("password", POLE_WYMAGANE, new String[] {
					POLE_HASLO }, null);
		} else if (cmd.getPassword().length() > MAX_LOGIN_LENGTH) {
			errors.rejectValue("password", POLE_ZA_DLUGIE, new String[] {
					POLE_HASLO, String.valueOf(MAX_LOGIN_LENGTH) }, null);
		} else if (!StringUtils.hasText(cmd.getRepeatedPassword())) {
			errors.rejectValue("repeatedPassword", POLE_WYMAGANE, new String[] {
					POLE_POWT_HASLO }, null);
		} else if (cmd.getRepeatedPassword().length() > MAX_LOGIN_LENGTH) {
			errors.rejectValue(
					"repeatedPassword",
					POLE_ZA_DLUGIE,
					new String[] { POLE_POWT_HASLO,
							String.valueOf(MAX_LOGIN_LENGTH) }, null);
		} else if (!cmd.getPassword().equals(cmd.getRepeatedPassword())) {
			errors.rejectValue("password", HASLA_NIE_SA_IDENTYCZNE);
		} else if(cmd.getPassword().equalsIgnoreCase(cmd.getName()) 
					|| cmd.getPassword().equalsIgnoreCase(cmd.getSurename())  
					|| cmd.getPassword().equalsIgnoreCase(cmd.getLogin())
					|| cmd.getPassword().equalsIgnoreCase(cmd.getPersonalNumber())
					|| cmd.getPassword().equalsIgnoreCase(cmd.getStreet())
					|| cmd.getPassword().equalsIgnoreCase(cmd.getZip())) {
			errors.rejectValue("password", HASLO_NIE_MOZE_BYC_JAK_DANE);
		}
		
		if(!StringUtils.hasText(cmd.getPersonalNumber())){
			errors.rejectValue("personalNumber", POLE_WYMAGANE, new String[] {
					POLE_PESEL }, null);
		} else if (cmd.getPersonalNumber().length() != MAX_PESEL_LENGTH) {
			errors.rejectValue("personalNumber", BLEDNA_LICZB_ZNAKOW_W_PESELU);
		} else {
			try {
				Long.parseLong(cmd.getPersonalNumber());
			} catch (NumberFormatException e){
				errors.rejectValue("personalNumber", BLEDNY_FORMAT_PESELU);
			}
		}
		
		if(!StringUtils.hasText(cmd.getStreet())){
			errors.rejectValue("street", POLE_WYMAGANE, new String[] {
					POLE_ULICA }, null);
		} else if (cmd.getStreet().length() > MAX_STREET_LENGTH) {
			errors.rejectValue("street", POLE_ZA_DLUGIE, new String[] {
					POLE_ULICA, String.valueOf(MAX_STREET_LENGTH) }, null);
		}
		
		try {
			Integer.parseInt(cmd.getFlatNumber());
		} catch (NumberFormatException e){
			errors.rejectValue("flatNumber", BLEDNY_FORMAT_NUMERU_DOMU);
		}
		
		if(!validationUtil.checkZipCode(cmd.getZip())){
			errors.rejectValue("zip", BLEDNY_FORMAT_KODU);
		} else if(!validationUtil.isZipInCity(cmd.getZip(), cmd.getCity())){
			errors.rejectValue("zip", KOD_NIE_NALEZY_DO_MIASTA);
		}
		
		if(!StringUtils.hasText(cmd.getTelephoneNumber())){
			errors.rejectValue("telephoneNumber", POLE_WYMAGANE, new String[] {
					POLE_TELEFON }, null);
		} else if(cmd.getTelephoneNumber().length() > MAX_PHONE_LENGTH){
			errors.rejectValue("telephoneNumber", POLE_ZA_DLUGIE, new String[] {
					POLE_TELEFON, String.valueOf(MAX_PHONE_LENGTH) }, null);
		} else if(!cmd.getTelephoneNumber().matches(NUMER_TEL_REGEXP)) {
			errors.rejectValue("telephoneNumber", NUMER_TEL_ZLY_FORMAT);
		}
	}
}
